package com.scy.factory;

import com.scy.anno.*;
import com.scy.utils.ClassUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class BeanFactory {

    private static Map<String,Object> map = new ConcurrentHashMap<String, Object>();

    private static Map<String,Object> beanMap = new HashMap<String, Object>();

    static{
        List<Class<?>> classList = ClassUtils.getAllClassByPackageName("com.scy");
        for (Class<?> aClass : classList) {
            Annotation[] annotations = aClass.getAnnotations();
            boolean isInterface = aClass.isInterface();
            Class[] face = aClass.getInterfaces();
            String name = aClass.getName();
            String anInterface = null;
            String[] annoList = null;
            Object object = null;
            Class<?> clazz = null;
            String beanId = "";
            String className = String.valueOf(aClass);
            try{
                if(className.startsWith("class")) {
                    if (!isInterface && face.length != 0) {
                        anInterface = String.valueOf(aClass.getInterfaces()[0]);
                        annoList = anInterface.split("\\.");
                    } else if (anInterface == null) {
                        annoList = name.split("\\.");
                    }
                    beanId = toLowerCaseFirstOne(annoList[annoList.length - 1]);
                    clazz = Class.forName(name);
                    if (className.indexOf("$1") < 0 && className.indexOf("$2") < 0 && className.indexOf("DruidUtils") < 0) {
                        object = clazz.newInstance();
                    }
                }
                if(aClass.isAnnotationPresent(Service.class) || aClass.isAnnotationPresent(MyProxy.class)|| aClass.isAnnotationPresent(MyRepository.class) || aClass.isAnnotationPresent(MyTransactionManager.class)){
                    map.put(beanId, object);
                }
                    beanMap.put(beanId,object);

            }catch (Exception e){
                e.printStackTrace();
            }
        }
        for(Map.Entry entry:beanMap.entrySet()){
            try{
                Object object = entry.getValue();
                if(object != null){
                    attriAssign(object);
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
        for(Map.Entry entry:map.entrySet()){
            try{
                Object object = entry.getValue();
                attriAssign(object);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static void attriAssign(Object object) throws Exception {
        Class<? extends Object> classInfo = object.getClass();
        Field[] declaredFields = classInfo.getDeclaredFields();
        // 2.判断当前类属性是否存在注解
        for (Field field : declaredFields) {
            Autowired autowired = field.getAnnotation(Autowired.class);
            if (autowired != null) {
                // 获取属性名称
                String beanId = field.getName();
                Object bean = null;
                if(beanMap.containsKey(beanId)){
                    bean = beanMap.get(beanId);
                }
                if (bean != null) {
                    // 3.默认使用属性名称，查找bean容器对象 1参数 当前对象 2参数给属性赋值
                    field.setAccessible(true); // 允许访问私有属性
                    field.set(object, bean);
                }
            }
        }
    }

    public static Object getBean(String id){
        Object o = map.get(id);
        return  o;
    }

    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }
}
